import axios, { AxiosInstance } from 'axios';

export interface AliBailianConfig {
  apiKey: string;
  baseUrl?: string;
}

export interface EmbeddingResponse {
  output: {
    embeddings: Array<{
      text_index: number;
      embedding: number[];
    }>;
  };
  usage: {
    total_tokens: number;
  };
  request_id: string;
}

export interface ChatResponse {
  output: {
    text: string;
  };
  usage: {
    input_tokens: number;
    output_tokens: number;
    total_tokens: number;
  };
  request_id: string;
}

export class AliBailianService {
  private client: AxiosInstance;
  private apiKey: string;

  constructor(config: AliBailianConfig) {
    this.apiKey = config.apiKey;
    
    this.client = axios.create({
      baseURL: config.baseUrl || 'https://dashscope.aliyuncs.com/api/v1',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
      },
      timeout: 30000, // 30秒超时
    });
  }

  /**
   * 生成文本嵌入向量
   * @param texts 要生成嵌入的文本数组
   * @param model 嵌入模型，默认使用 text-embedding-v3
   */  async generateEmbeddings(texts: string[], model: string = 'text-embedding-v3'): Promise<number[][]> {
    try {      const response = await this.client.post<EmbeddingResponse>('/services/embeddings/text-embedding/text-embedding', {
        model,
        input: {
          texts,
        },
        parameters: {
          text_type: 'document' // 设置文本类型为文档
        }
      });

      if (!response.data.output?.embeddings) {
        throw new Error('Invalid response format: missing embeddings');
      }

      // 按 text_index 排序并返回嵌入向量
      const embeddings = response.data.output.embeddings
        .sort((a, b) => a.text_index - b.text_index)
        .map(item => item.embedding);

      return embeddings;
    } catch (error) {
      console.error('Error generating embeddings:', error);
      if (axios.isAxiosError(error)) {
        const status = error.response?.status;
        const message = error.response?.data?.message || error.message;
        throw new Error(`Embedding API error (${status}): ${message}`);
      }
      throw error;
    }
  }

  /**
   * 生成单个文本的嵌入向量
   * @param text 要生成嵌入的文本
   * @param model 嵌入模型，默认使用 text-embedding-v3
   */
  async generateEmbedding(text: string, model: string = 'text-embedding-v3'): Promise<number[]> {
    const embeddings = await this.generateEmbeddings([text], model);
    return embeddings[0];
  }

  /**
   * 生成文本内容
   * @param prompt 输入的提示词
   * @param model 生成模型，默认使用 qwen-plus-latest
   * @param options 生成选项
   */
  async generateText(
    prompt: string, 
    model: string = 'qwen-plus-latest',
    options: {
      temperature?: number;
      top_p?: number;
      top_k?: number;
      max_tokens?: number;
    } = {}
  ): Promise<string> {
    try {
      const {
        temperature = 0.3,
        top_p = 0.9,
        top_k = 40,
        max_tokens = 2000,
      } = options;

      const response = await this.client.post<ChatResponse>('/services/aigc/text-generation/generation', {
        model,
        input: {
          messages: [
            {
              role: 'user',
              content: prompt,
            },
          ],
        },
        parameters: {
          temperature,
          top_p,
          top_k,
          max_tokens,
          result_format: 'text',
        },
      });

      if (!response.data.output?.text) {
        throw new Error('Invalid response format: missing text');
      }

      return response.data.output.text.trim();
    } catch (error) {
      console.error('Error generating text:', error);
      if (axios.isAxiosError(error)) {
        const status = error.response?.status;
        const message = error.response?.data?.message || error.message;
        throw new Error(`Text generation API error (${status}): ${message}`);
      }
      throw error;
    }
  }

  /**
   * 检查 API 连接状态
   */
  async checkConnection(): Promise<boolean> {
    try {
      // 使用一个简单的请求来测试连接
      await this.generateEmbedding('test connection', 'text-embedding-v3');
      return true;
    } catch (error) {
      console.error('Connection check failed:', error);
      return false;
    }
  }
}
